#pragma once

#include <sys/epoll.h>
#include "noncopy.hpp"

class Epoller : public noncopy
{
    static const int epoll_size = 128;

public:
    Epoller()
    {
        _epfd = epoll_create(epoll_size);
        if (_epfd < 0)
            lg(Error, "epoll create error, error string: %S", strerror(errno)); // 错误消息顺便输出
        else
            lg(Info, "epoll create success, fd: %d", _epfd);
    }

    int EpollControl(int oper, int fd, uint32_t events)
    {
        int n = 0; // 多次使用，可写在外面
        // if(oper & EPOLL_CTL_DEL)
        if (oper == EPOLL_CTL_DEL)
        {
            n = epoll_ctl(_epfd, oper, fd, nullptr);
            if (n < 0)
                lg(Warning, "epoll_ctl delete error");
            else
                lg(Info, "epoll_ctl delete success");
        }
        else
        {
            struct epoll_event event;
            event.data.fd = fd;
            event.events = events;
            n = epoll_ctl(_epfd, oper, fd, &event);
            if (n < 0)
                lg(Warning, "epoll_ctl %d error", oper);
            else
                lg(Info, "epoll_ctl %d success", oper);
        }
        return n; // 可返回结果
    }

    int EpollWait(struct epoll_event *events, int max_events)
    {
        int n = epoll_wait(_epfd, events, max_events, _timeout);
        return n;
    }

    ~Epoller() // 不用时记得在析构时释放
    {
        if (_epfd >= 0)
            close(_epfd);
    }

private:
    int _epfd;
    int _timeout = 3000;
};